<?php

declare(strict_types=1);

namespace core;

class Validation
{

    public $data;
    public $checkRules;
    public $error;
    public $checkToken;

    public function __construct($data, $checkRules, $checkToken = false)
    {
        $this->data       = $data;
        $this->checkRules = $checkRules;
        $this->checkToken = $checkToken;
    }

    public function check()
    {
        if ($this->checkToken) {
            $token = escape($_POST['csrf_token']);
            if (!$token || $token !== $_SESSION['csrf_token']) {
                $this->error = 'token error';
                return false;
            }
        }

        foreach ($this->checkRules as $k => $rule) {
            if (!isset($this->data[$k])) {
                $this->error = $rule[2];
                return false;
            }
            if (is_array($rule[0])) {
                foreach ($rule as $ruleNew) {
                    $methodName = 'check' . ucfirst($ruleNew[0]);
                    if (!method_exists($this, $methodName)) {
                        exit('数据检查规则配置错误1');
                    }
                    $res = $this->$methodName($this->data[$k], $ruleNew[1]);
                    if (!$res) {
                        $this->error = $ruleNew[2];
                        return false;
                    }
                }
            } else {
                $methodName = 'check' . ucfirst($rule[0]);
                if (!method_exists($this, $methodName)) {
                    exit('数据检查规则配置错误');
                }
                $res = $this->$methodName($this->data[$k], $rule[1]);
                if (!$res) {
                    $this->error = $rule[2];
                    return false;
                }
            }
        }
        return true;
    }

    // 不为空
    public function checkRequired($value, $between)
    {
        return !empty($value) && preg_match('#^.{' . $between . '}$#Uis', trim($value));
        // return (!is_null($value) || is_string($value) && trim($value) === '');
    }

    // 字符串及长度检查
    public function checkString($data, $rule)
    {
        return preg_match('/^.{' . $rule . '}$/Uis', trim($data));
    }

    // 整数检查
    public function checkIsInt($value, $placeholder = null)
    {
        // return preg_match('/^\-?[0-9]+$/', $checkData);
        return filter_var($value, FILTER_VALIDATE_INT);
    }

    // 整数及长度检查
    public function checkInt($checkData, $checkRule)
    {
        return preg_match('/^\-?[0-9]{' . $checkRule . '}$/', $checkData);
    }

    // 整数及区间
    public function checkBetweend($checkData, $checkRule)
    {
        if (!$this->checkIsInt($checkData)) {
            return false;
        }
        $checkRules = explode(',', $checkRule);
        if ($checkData > $checkRules[1] || $checkData < $checkRules[0]) {
            return false;
        }
        return true;
    }

    // 数值区间
    public function checkBetween($checkData, $checkRule)
    {
        $checkRules = explode(',', $checkRule);
        if ($checkData > $checkRules[1] || $checkData < $checkRules[0]) {
            return false;
        }
        return true;
    }

    // 小数检查
    public function checkIsFloat($checkData, $placeholder = null)
    {
        return preg_match('/^(\d+)\.(\d+)$/', $checkData);
    }

    // 小数及区间检查
    public function checkBetweenf($checkData, $checkRule)
    {
        if (!$this->checkIsFloat($checkData)) {
            return false;
        }
        $checkRules = explode(',', $checkRule);
        if ($checkData > $checkRules[1] || $checkData < $checkRules[0]) {
            return false;
        }
        return true;
    }

    // 小数及小数位数检查
    public function checkFloatLenght($checkData, $checkRule)
    {
        if (!$this->checkIsFloat($checkData)) {
            return false;
        }
        return preg_match('/^(\d+)\.(\d{' . $checkRule . '})$/', $checkData);
    }

    // 大于
    public function checkGt($checkData, $checkRule)
    {
        return ($checkData > $checkRule);
    }

    // 大于等于
    public function checkGtAndSame($checkData, $checkRule)
    {
        return ($checkData >= $checkRule);
    }

    // 小于
    public function checkLt($checkData, $checkRule)
    {
        return ($checkData < $checkRule);
    }

    // 小于等于
    public function checkLtAndSame($checkData, $checkRule)
    {
        return ($checkData <= $checkRule);
    }

    // 等于
    public function checkSame($checkData, $checkRule)
    {
        return ($checkData === $checkRule);
    }

    // 不等于
    public function checkNotSame($checkData, $checkRule)
    {
        return ($checkData !== $checkRule);
    }

    // 邮箱
    public function checkEmail($email, $placeholder = null)
    {
        // return preg_match('/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', $checkData);
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

    // 手机号
    public function checkPhone($checkData, $checkRule)
    {
        return preg_match('/^13[0-9]{9}$|14[0-9]{9}$|15[0-9]{9}$|18[0-9]{9}$|17[0-9]{9}$/', $checkData);
    }

    // url
    public function checkUrl($checkData, $placeholder = null)
    {
        // return preg_match('/^(\w+:\/\/)?\w+(\.\w+)+.*$/', $checkData);
        return filter_var($checkData, FILTER_VALIDATE_URL);
    }

    // 邮编
    public function checkZipcode($checkData, $placeholder = null)
    {
        return preg_match('/^[0-9]{6}$/', $checkData);
    }

    // 正则
    public function checkReg($checkData, $placeholder = null)
    {
        // return preg_match('/^' . $checkRule . '$/', $checkData);
        return filter_var($checkData, FILTER_VALIDATE_REGEXP);
    }
}
